home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / security / xinetd / fsma.2.0.1 / fsma.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-08  |  5.7 KB  |  258 lines

  1. /*
  2.  * (c) Copyright 1992 by Panagiotis Tsirigotis
  3.  * All rights reserved.  The file named COPYRIGHT specifies the terms 
  4.  * and conditions for redistribution.
  5.  */
  6.  
  7. /*
  8.  * $Id: fsma.c,v 5.1 1992/10/10 07:23:18 panos Exp $
  9.  */
  10.  
  11. #include "fsma.h"
  12. #include "impl.h"
  13.  
  14. #ifdef DEBUG
  15. #include <stdio.h>
  16. #endif
  17.  
  18. /*
  19.  * We assume that memory handed by malloc is suitably aligned for any
  20.  * machine data type (for example, if the CPU wants double's aligned
  21.  * at an 8-byte boundary, the memory provided by malloc will be so aligned).
  22.  */
  23. char *malloc() ;
  24. int free() ;
  25.  
  26. static char *version = VERSION ;
  27.  
  28. PRIVATE void init_free_list __ARGS( ( unsigned, unsigned, char * ) ) ;
  29. PRIVATE void terminate __ARGS( ( char * ) ) ;
  30.  
  31.  
  32. /*
  33.  * An allocator manages a linked list of chunks:
  34.  *
  35.  *        ______________            ______________            ______________
  36.  *        |   HEADER     |------>|                 |------>|                 |
  37.  *        |____________|            |____________|            |____________|
  38.  *        |                  |            |                  |            |                  |
  39.  *        |                  |            |                  |            |                  |
  40.  *        |                  |            |                  |            |                  |
  41.  *        |                  |            |                  |            |                  |
  42.  *        |     SLOTS     |            |                  |            |                  |
  43.  *        |                  |            |                  |            |                  |
  44.  *        |                  |            |                  |            |                  |
  45.  *        |                  |            |                  |            |                  |
  46.  *        |                  |            |                  |            |                  |
  47.  *        |____________|            |____________|            |____________|
  48.  *
  49.  *
  50.  * The SLOTS sections are organized as a linked list of slots whose
  51.  * size is determined by the object size specified in fsm_create
  52.  */
  53.  
  54. fsma_h fsm_create( object_size, slots_per_chunk, flags )
  55.     unsigned object_size ;
  56.     unsigned slots_per_chunk ;
  57.     int flags ;
  58. {
  59.     register fsma_h fp ;
  60.     union __fsma_chunk_header *chp ;
  61.     char *slots ;
  62.     unsigned nslots ;
  63.     unsigned chunk_size, slot_size ;
  64.     int header_inlined ;
  65.  
  66.     slot_size = ( object_size < MINSIZE ) ? MINSIZE : object_size ;
  67.     nslots = ( slots_per_chunk == 0 ) ? SLOTS_PER_CHUNK : slots_per_chunk ;
  68.  
  69.     chunk_size = sizeof( union __fsma_chunk_header ) + nslots * slot_size ;
  70.  
  71.     chp = CHUNK_HEADER( malloc( chunk_size ) ) ;
  72.     if ( chp == NULL )
  73.         if ( flags & FSM_RETURN_ERROR )
  74.             return( NULL ) ;
  75.         else
  76.             terminate( "FSMA fsm_create: malloc failed\n" ) ;
  77.  
  78.     slots = (char *) &chp[ 1 ] ;
  79.     init_free_list( nslots, slot_size, slots ) ;
  80.  
  81. #ifdef DEBUG
  82.     {
  83.         int i ;
  84.  
  85.         fprintf( stderr, "Size = %d, nslots = %d\n", slot_size, nslots ) ;
  86.         for ( i = 0 ; i < nslots+1 ; i++ )
  87.             fprintf( stderr, "slot[ %d ] = %p\n",
  88.                             i, (*(char **) (slots + i * slot_size ))) ;
  89.     }
  90. #endif
  91.  
  92.     /*
  93.      * Check if we can fit the header in an object slot
  94.      */
  95.     if ( slot_size >= sizeof( struct __fsma_header ) )
  96.     {
  97.         /*
  98.          * We can do it.
  99.          * Allocate the first slot
  100.          */
  101.         fp = (fsma_h) slots ;
  102.         slots = *(POINTER *) slots ;
  103.         header_inlined = TRUE ;
  104.     }
  105.     else
  106.     {
  107.         fp = (fsma_h) malloc( sizeof( struct __fsma_header ) ) ;
  108.         if ( fp == NULL )
  109.             if ( flags & FSM_RETURN_ERROR )
  110.             {
  111.                 free( (char *) chp ) ;
  112.                 return( NULL ) ;
  113.             }
  114.             else
  115.                 terminate( "FSMA fsm_create: malloc of header failed\n" ) ;
  116.         header_inlined = FALSE ;
  117.     }
  118.  
  119.     chp->next_chunk = NULL ;
  120.  
  121.     fp->next_free = (POINTER) slots ;
  122.     fp->chunk_chain = chp ;
  123.     fp->slots_in_chunk = nslots ;
  124.     fp->slot_size = slot_size ;
  125.     fp->chunk_size = chunk_size ;
  126.     fp->flags = flags ;
  127.     fp->is_inlined = header_inlined ;
  128.  
  129. #ifdef DEBUG
  130.     fprintf( stderr, "Slots/chunk = %d\n", nslots ) ;
  131.     fprintf( stderr, "Allocating chunk %p\n", chunk ) ;
  132. #endif
  133.     
  134.     return( (fsma_h) fp ) ;
  135. }
  136.  
  137.  
  138.  
  139. void fsm_destroy( fp )
  140.     register fsma_h fp ;
  141. {
  142.     int header_inlined = fp->is_inlined ;
  143.     register union __fsma_chunk_header *chp, *next_chunk ;
  144.     register int zero_memory = fp->flags & FSM_ZERO_DESTROY ;
  145.     register chunk_size = fp->chunk_size ;
  146.  
  147.     /*
  148.      * Free all chunks in the chunk chain
  149.      */
  150.     for ( chp = fp->chunk_chain ; chp != NULL ; chp = next_chunk )
  151.     {
  152.         next_chunk = chp->next_chunk ;
  153.         if ( zero_memory )
  154.             (void) memset( (char *)chp, 0, chunk_size ) ;
  155.  
  156. #ifdef DEBUG
  157.         fprintf( stderr, "Freeing chunk %p\n", chp ) ;
  158. #endif
  159.         free( (char *)chp ) ;
  160.     }
  161.  
  162.     /*
  163.      * If fp->inlined is NO, we have to free the handle.
  164.      * Note that we copied fp->inlined in case it is YES.
  165.      */
  166.     if ( ! header_inlined )
  167.         free( (char *)fp ) ;
  168. }
  169.  
  170.  
  171. char *_fsm_alloc( fp )
  172.     register fsma_h fp ;
  173. {
  174.     register POINTER object ;
  175.  
  176.     /*
  177.      * Check if there are any slots on the free list
  178.      */
  179.     if ( fp->next_free == NULL )
  180.     {
  181.         /*
  182.          * Free list exhausted; allocate a new chunk
  183.          */
  184.         char *slots ;
  185.         union __fsma_chunk_header *chp ;
  186.  
  187.         chp = CHUNK_HEADER( malloc( fp->chunk_size ) ) ;
  188.         if ( chp == NULL )
  189.             if ( fp->flags & FSM_RETURN_ERROR )
  190.                 return( NULL ) ;
  191.             else
  192.                 terminate( "FSMA fsm_alloc: malloc failed\n" ) ;
  193.  
  194. #ifdef DEBUG
  195.         fprintf( stderr, "Allocating chunk %p\n", chunk ) ;
  196. #endif
  197.         /*
  198.          * Put the slots in this chunk in a linked list
  199.          * and add this list to the free list
  200.          */
  201.         slots = (char *) &chp[ 1 ] ;
  202.         init_free_list( fp->slots_in_chunk, fp->slot_size, slots ) ;
  203.         fp->next_free = (POINTER) slots ;
  204.  
  205.         /*
  206.          * Put this chunk at the head of the chunk chain
  207.          */
  208.         chp->next_chunk = fp->chunk_chain ;
  209.         fp->chunk_chain = chp ;
  210.     }
  211.  
  212.     object = fp->next_free ;
  213.     fp->next_free = *(POINTER *)object ;
  214.  
  215.     if ( fp->flags & FSM_ZERO_ALLOC )
  216.         (void) memset( object, 0, fp->slot_size ) ;
  217.  
  218.     return( object ) ;
  219. }
  220.  
  221.  
  222. void _fsm_free( fp, object )
  223.     fsma_h fp ;
  224.     char *object ;
  225. {
  226.     if ( fp->flags & FSM_ZERO_FREE )
  227.         (void) memset( object, 0, fp->slot_size ) ;
  228.  
  229.     *(POINTER *)object = fp->next_free ;
  230.     fp->next_free = object ;
  231. }
  232.  
  233.  
  234. PRIVATE void terminate( s )
  235.     char *s ;
  236. {
  237.     write( 2, s, strlen( s ) ) ;
  238.     abort() ;
  239.     exit( 1 ) ;
  240. }
  241.  
  242.  
  243. PRIVATE void init_free_list( nslots, size, slots )
  244.     unsigned nslots ;
  245.     register unsigned size ;
  246.     char *slots ;
  247. {
  248.     register int i ;
  249.     register char *next ;
  250.     register POINTER current ;
  251.  
  252.     for ( i = 0, current = slots, next = slots + size ; i < nslots - 1 ;
  253.                                                         i++, current = next, next += size )
  254.         *(POINTER *)current = next ;
  255.     *(POINTER *)current = NULL ;
  256. }
  257.  
  258.